# --------------------------------------------------------------------------------
#  NoiseTube Web application
#  
#  Copyright (C) 2008-2010 SONY Computer Science Laboratory Paris
#  Portions contributed by Vrije Universiteit Brussel (BrusSense team), 2008-2011
# --------------------------------------------------------------------------------
#  This library is free software; you can redistribute it and/or modify it under
#  the terms of the GNU Lesser General Public License, version 2.1, as published
#  by the Free Software Foundation.
#  
#  This library is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
#  details.
#  
#  You should have received a copy of the GNU Lesser General Public License along
#  with this library; if not, write to:
#    Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor,
#    Boston, MA  02110-1301, USA.
#  
#  Full GNU LGPL v2.1 text: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
#  NoiseTube project source code repository: http://code.google.com/p/noisetube
# --------------------------------------------------------------------------------
#  More information:
#   - NoiseTube project website: http://www.noisetube.net
#   - Sony Computer Science Laboratory Paris: http://csl.sony.fr
#   - VUB BrusSense team: http://www.brussense.be
# --------------------------------------------------------------------------------
 
require 'time'
require 'sound_level.rb'
require 'rgeo'

class Cartasur::Measure < Measure
  establish_connection "cartasur_#{Rails.env}"


  belongs_to :track, :class_name => 'Cartasur::Track'
  belongs_to :user, :class_name => 'Cartasur::User'

  validates_numericality_of :loudness
  validates_presence_of :user
  validates_presence_of :track

  attr_accessible :user, :track, :made_at, :loudness, :loudness_index, :geom, :is_objective_gps

  @geographic_factory = RGeo::Geographic.spherical_factory(:srid => 4326)
  # Support Cartesian (flat) geometry
  #geographic_factory = RGeo::Geographic.spherical_factory(:srid => 4326)

  #acts_as_geom :geom  => :point
  #acts_as_taggable_on :tags, :autoclienttags

  # depre6  save the noise exposure with its meta-data
  #@param params - the params from the request
  #@param track - the running track
  #@param user - the user performing the update
  def self.save_request(params, track, user)

    # time
    made_at = Time.now
    made_at = DateTime.parse(params[:time]) unless params[:time].blank?
    tag_args = {:with => params[:tag], :on => :location}

    # store the measure
    measure=Cartasur::Measure.new(:made_at=>made_at,
                        :loudness=> params[:db],
                        :user=>user,
                        :track=>track)

    #loudness_index
    measure.loudness_index = SoundLevel.compute_loudness_index(measure.loudness)

    # location
    loc = params[:l]
    # if location is lat,lng coordinates
    if loc=~ /geo\:(.*),(.*)/
      measure.geom=@geographic_factory.point($2.to_f, $1.to_f)
      #measure.geom.srid = 4326 #WGS84
    else
      # if location is tag location
      tag_args = {:with => loc.downcase, :on => "location"} unless loc.blank?
    end



    #TAGGING
    #automatic tags passed as normal tags by older NTMobile versions
    if params[:tag]=="variation:high"
      measure.peak=1
    elsif params[:tag]=="exposure:high"
      measure.longexposure=1
    else
      unless params[:tag].blank?
        #human tags
        #params[:tag].split(/ |,|;/).each { |t|  #split at spaces, commas and semicolons (tagging framework only splits at spaces)
        #  logger.error t

        tag_args = {:with=>params[:tag], :on=>"user"}
        #}
      end
    end

    #new way of passing automatic tags from NTMobile client: all tags take form "tagger:tag", they are space-separated (e.g.: "tagger1:tagA tagger2:tagB")
    unless params[:autotag].blank?
      tag_args = { :with=>params[:autotag], :on=>"auto"}
    end

    # ozone
    #measure.ozone=params[:ozone].to_i unless params[:ozone].blank?
    measure.save
    logger.info "Saved measurement. ID:" + measure.id.to_s + " track: " + measure.track.id.to_s + " by user: " + measure.user.id.to_s

    measure_tag = Cartasur::MeasurementsTag.new(
        tag_name: tag_args[:with],
        track: track,
        begin_id: measure.id,
        end_id: measure.id,
        context: tag_args[:on],
        user: user
    )
    measure_tag.connection
    #save the tag. todo: how to handle tag intervals in api
    measure_tag.save!
  end

  # function save_measurements_as_transactions - saves measures as batch
  #@param query - the starting query
  #@param values - the values array
  def self.save_as_transactions(query, values)
    ids = []
    sql = query << values.join(",") << " RETURNING id"
    self.transaction do
      result = self.connection.execute sql
      #return ids as array
      result.each do |row|
        ids << row["id"] unless row["id"].nil?
      end
    end
    ids
  end

end
